import { contextMenu } from './context-menu-config';
import { cloneDeep } from 'lodash-es';
import FdContainerBaseComponent from '../../common/containerBase/containerBase';
import { RowNode } from '@farris/ui-treetable';
import { ContextMenuManager } from '../../../../service/context-menu.manager';
import { ControlContextMenuItem } from '../../../../entity/control-context-menu';
import { ComponentSchema, IControlService } from '@farris/designer-element';
import { DgControl } from '../../../../utils/dg-control';
import { MessagerService } from '@farris/ui-messager';
import { ControlService } from '../../../../service/control.service';

const CHANGE_TO_TAB = 'changeToTab';
const MOVE_TO_TAB = 'moveToTab';

export class SectionContextMenuManager extends ContextMenuManager {

    private controlService: IControlService;
    private msgService: MessagerService;

    constructor(cmp: FdContainerBaseComponent, rowNode: RowNode) {
        super(cmp, rowNode);

        this.controlService = this.injector.get(ControlService);
        this.msgService = this.injector.get(MessagerService);
    }
    /**
     * 过滤、修改控件树右键菜单
     */
    setContextMenuConfig() {
        let menuConfig = cloneDeep(contextMenu) as ControlContextMenuItem[];

        menuConfig = this.assembleChangeToTabMenu(this.cmpInstance.component, menuConfig);

        menuConfig = this.assembleMoveToTabMenu(this.cmpInstance.component, menuConfig);

        // 配置菜单点击事件
        this.addContextMenuHandle(menuConfig);

        return menuConfig || [];
    }

    /**
     * 点击控件树右键菜单
     */
    contextMenuClicked(e: { data: RowNode, menu: ControlContextMenuItem }) {

        const menu = e.menu;
        if (menu.id === CHANGE_TO_TAB) {
            this.changeToTab(this.cmpInstance.component);
            return;
        }
        if (menu.parentMenuId === MOVE_TO_TAB) {
            this.moveToTab(this.cmpInstance.component, menu.id);
            return;
        }

        this.notifyService.warning('暂不支持');
    }

    /**
     * 组装是否支持切换为标签页Tab的菜单
     * @param dgSectionElement 当前标签页节点
     * @param menuConfig 右键菜单
     */
    private assembleChangeToTabMenu(sectionElement: ComponentSchema, menuConfig: ControlContextMenuItem[]) {

        const changeToTabMenu = menuConfig.find(menu => menu.id === CHANGE_TO_TAB);
        if (!changeToTabMenu) {
            return menuConfig;
        }

        const checkResult = this.checkCanChangeToTab(sectionElement, changeToTabMenu.title);
        if (checkResult) {
            menuConfig = menuConfig.filter(menu => menu.id !== CHANGE_TO_TAB);
        }
        return menuConfig;

    }

    private checkCanChangeToTab(sectionElement: ComponentSchema, menuName: string) {

        // 1、限制section的class样式
        const sectionClass = sectionElement.appearance && sectionElement.appearance.class;
        if (!sectionClass || !(sectionClass.includes('f-section-in-mainsubcard') || sectionClass.includes('f-section-in-main'))) {
            return '分组面板的class样式不包含f-section-in-mainsubcard或f-section-in-main，不支持' + menuName;
        }

        // 2、标准模板规定container-section-tab 是成对出现三层结构，转换后的section结构也是container-section
        const dgContainerElement = this.cmpInstance.parent.component;
        if (!dgContainerElement || dgContainerElement.type !== DgControl.ContentContainer.type) {
            return '分组面板的父级不是ConentContainer容器，不支持' + menuName;
        }

        // 3、限制父级container样式
        if (!dgContainerElement.appearance || !dgContainerElement.appearance.class || !dgContainerElement.appearance.class.includes('f-struct-wrapper')) {
            return 'ContentContainer容器的class样式不包含f-struct-wrapper，不支持' + menuName;
        }

        // 4、子级中已有标签页节点，则不支持切换标签页
        const tabElement = sectionElement.contents.find(item => item.type === DgControl.Tab.type);
        if (tabElement) {
            return '分组面板的子级已有标签页节点，不支持' + menuName;
        }

        return;
    }

    /**
     * Section切换为Tab。
     * Container-Section-ComponentRef 切换为Contaienr-Section-Tab-TabPage-ComponentRef
     * @param dgSectionElement section元素
     */
    private changeToTab(sectionElement: ComponentSchema) {
        this.msgService.question('面板切换为标签页后，将仅保留主标题、按钮属性，确定切换？', () => {

            const idPostfix = this.getControlIdPostfix(sectionElement);

            // 新建tab
            const tabMetadata = this.controlService.getControlMetaData(DgControl.Tab.type);
            tabMetadata.id = 'detail-tab-' + idPostfix; // 可能会重复？

            // 新建tabPage
            const tabPage = this.controlService.getControlMetaData(DgControl.TabPage.type);
            tabPage.id = 'tab-page-' + idPostfix;
            tabPage.title = sectionElement.mainTitle;
            tabPage.contents = sectionElement.contents;
            tabPage.multiViews = sectionElement.multiViews;
            tabPage.views = sectionElement.views;

            // 配置tabPage按钮
            if (sectionElement.toolbar && sectionElement.toolbar.contents && sectionElement.toolbar.contents.length) {
                tabPage.toolbar.id = 'tabToolbar-' + idPostfix;
                tabPage.toolbar.position = sectionElement.toolbar.position;

                sectionElement.toolbar.contents.forEach(sectionToolbarItem => {
                    sectionToolbarItem.type = DgControl.TabToolbarItem.type;
                    tabPage.toolbar.contents.push(sectionToolbarItem);
                });
                sectionElement.toolbar.contents = [];
            }

            tabMetadata.contents = [tabPage];
            tabMetadata.selected = tabPage.id;

            // tab样式要根据section的样式来区分
            const sectionClassArray = sectionElement.appearance.class.split(' ');
            if (sectionClassArray.includes('f-section-in-mainsubcard')) {
                tabMetadata.appearance = {
                    class: 'f-component-tabs f-tabs-has-grid'
                };
            }
            if (sectionClassArray.includes('f-section-in-main')) {
                tabMetadata.appearance = {
                    class: 'f-component-tabs'
                };
            }


            // 变更原section样式、头部、内容区
            if (!sectionClassArray.includes('f-section-tabs')) {
                sectionElement.appearance.class = 'f-section-tabs ' + sectionElement.appearance.class;
            }
            sectionElement.showHeader = false;
            sectionElement.mainTitle = '';
            sectionElement.contents = [tabMetadata];



            this.notifyService.success('切换成功');

            // this.formService.closePropertyPanel.next();
            this.refreshFormService.refreshFormDesigner.next();

        });

    }


    /**
     * 组装是否支持移动至Tab的菜单
     * @param dgSectionElement 当前标签页节点
     * @param menuConfig 右键菜单
     */
    assembleMoveToTabMenu(sectionElement: ComponentSchema, menuConfig: ControlContextMenuItem[]) {

        const moveToTabMenu = menuConfig.find(menu => menu.id === MOVE_TO_TAB);
        if (!moveToTabMenu) {
            return menuConfig;
        }

        const checkResult = this.checkCanChangeToTab(sectionElement, moveToTabMenu.title);
        if (checkResult) {
            menuConfig = menuConfig.filter(menu => menu.id !== MOVE_TO_TAB);
            return menuConfig;
        }

        // 校验父容器container的同级中有没有Container--->Tab 的层级结构
        const grandParentContaienr = this.cmpInstance.parent.parent.component;

        moveToTabMenu.children = [];
        grandParentContaienr.contents.forEach(container => {
            if (container.type !== DgControl.ContentContainer.type) {
                return;
            }
            const tabNode = this.domService.selectNode(container, item => item.type === DgControl.Tab.type);
            if (tabNode) {
                moveToTabMenu.children.push({
                    id: tabNode.id,
                    title: tabNode.id
                });
            }
        });

        if (moveToTabMenu.children.length === 0) {
            menuConfig = menuConfig.filter(menu => menu.id !== MOVE_TO_TAB);
        }

        return menuConfig;

    }

    /**
     * section移动至标签页
     * Container-Section-ComponentRef 切换为TabPage-ComponentRef
     * @param dgSectionElement section元素
     * @param targetTabId 目标标签页id
     */
    moveToTab(sectionElement: ComponentSchema, targetTabId: string) {
        this.msgService.question('面板移动至标签页后，将仅保留主标题、按钮属性，确定切换？', () => {
            const tabElement = this.domService.domDgMap.get(targetTabId);

            const idPostfix = this.getControlIdPostfix(sectionElement);

            // 新建tabPage
            const tabPageMetadata = this.controlService.getControlMetaData(DgControl.TabPage.type);
            tabPageMetadata.id = 'tab-page-' + idPostfix;
            tabPageMetadata.title = sectionElement.mainTitle;
            tabPageMetadata.contents = sectionElement.contents;
            tabPageMetadata.multiViews = sectionElement.multiViews;
            tabPageMetadata.views = sectionElement.views;

            // 配置tabPage按钮
            if (sectionElement.toolbar && sectionElement.toolbar.contents && sectionElement.toolbar.contents.length) {
                tabPageMetadata.toolbar.id = 'tabToolbar-' + idPostfix;
                tabPageMetadata.toolbar.position = sectionElement.toolbar.position;

                sectionElement.toolbar.contents.forEach(sectionToolbarItem => {
                    sectionToolbarItem.type = DgControl.TabToolbarItem.type;
                    tabPageMetadata.toolbar.contents.push(sectionToolbarItem);
                });
                sectionElement.toolbar.contents = [];
            }

            tabElement.contents.push(tabPageMetadata);

            // 移除section的父容器
            const grandParentContaienr = this.cmpInstance.parent.parent.component;
            grandParentContaienr.contents = grandParentContaienr.contents.filter(c => c.id !== this.cmpInstance.parent.id);


            this.notifyService.success('移动成功');

            // 因为当前section已经被移除，所以需要清除属性面板的数据
            this.cmpInstance.emit('clearPropertyPanel');

            this.refreshFormService.refreshFormDesigner.next();
        });

    }
    /**
     * 根据section的上下文获取新建控件的id后缀
     * @param sectionElement section元素
     */
    private getControlIdPostfix(sectionElement: any) {
        let idPostfix = Math.random().toString(36).substr(2, 4);
        const componentRef = sectionElement.contents.find(c => c.type === DgControl.ComponentRef.type);
        if (componentRef) {
            idPostfix = componentRef.id.replace('-component-ref', '');
        }
        const multiViewContainer = sectionElement.contents.find(c => c.type === DgControl.MultiViewContainer.type);
        if (multiViewContainer) {
            idPostfix = multiViewContainer.dataSource + '-' + idPostfix;
        }

        return idPostfix;
    }

}

